import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.RemoteException;
import java.text.NumberFormat;
import java.util.Properties;
import java.util.Set;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;

public class MainView extends JPanel {
	private static final long serialVersionUID = 1L;
	private WarehouseInterface server;
	private JTable table;
	private JLabel selected;
	private JTextField nameField;
	private JButton newSession;
	private JTextField amountField;
	private JButton newOrder;
	private JButton newConfirm;
	private OverviewManager manager;
	private JLabel message;
	private JEditorPane overview;
	@SuppressWarnings("rawtypes")
	private JComboBox dropdown;
	private JScrollPane editorScrollPane;
	private String name;
	private int id;
	private NumberFormat nf;

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public MainView(WarehouseInterface server) {
		this.server = server;
		nf = NumberFormat.getInstance();
		nf.setMaximumFractionDigits(2);
		nf.setMinimumFractionDigits(2);
		nf.setGroupingUsed(false);
		manager = new OverviewManager(nf);

		setLayout(new BorderLayout());

		JPanel center = new JPanel();
		center.setLayout(new GridLayout(1, 2));

		JPanel left = new JPanel();
		left.setLayout(new BoxLayout(left, BoxLayout.Y_AXIS));
		Object[][] data = createTableContent("");
		table = new JTable(new ProductTableModel(data));
		table.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
		left.add(new JScrollPane(table));
		table.setEnabled(false);
		String[] petStrings = { "", "huis", "tuin", "werk", "auto" };
		dropdown = new JComboBox(petStrings);
		dropdown.addActionListener(new dropdownHandler());
		dropdown.setEnabled(false);
		left.add(dropdown);

		selected = new JLabel("Alle producten");
		left.add(selected);

		JPanel bottomFirst = new JPanel();
		bottomFirst.setLayout(new FlowLayout());
		JLabel nameLabel = new JLabel("Naam:");
		bottomFirst.add(nameLabel);
		nameField = new JTextField(8);
		bottomFirst.add(nameField);
		newSession = new JButton("Nieuwe winkelmand");
		newSession.addActionListener(new sessionHandler());
		bottomFirst.add(newSession);
		left.add(bottomFirst);

		JPanel right = new JPanel();
		right.setLayout(new BorderLayout());

		JPanel bottomSecond = new JPanel();
		bottomSecond.setLayout(new FlowLayout());
		JLabel amountLabel = new JLabel("Aantal:");
		bottomSecond.add(amountLabel);
		amountField = new JTextField(6);
		amountField.setEnabled(false);
		bottomSecond.add(amountField);
		newOrder = new JButton("Plaats in winkelmand");
		newOrder.addActionListener(new orderHandler());
		newOrder.setEnabled(false);
		bottomSecond.add(newOrder);

		JPanel bottomThird = new JPanel();
		bottomThird.setLayout(new FlowLayout());

		newConfirm = new JButton("Bevestig bestelling");
		newConfirm.addActionListener(new confirmHandler());
		newConfirm.setEnabled(false);
		bottomThird.add(newConfirm);

		JPanel bottomFourth = new JPanel();
		bottomFourth.setLayout(new FlowLayout());

		overview = new JEditorPane();
		overview.setEditable(false);
		overview.setPreferredSize(new Dimension(400, 400));
		// Put the editor pane in a scroll pane.
		editorScrollPane = new JScrollPane(overview,
				JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
				JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

		bottomFourth.add(overview);

		right.add(bottomSecond, BorderLayout.PAGE_START);
		right.add(bottomThird, BorderLayout.PAGE_END);
		right.add(bottomFourth, BorderLayout.CENTER);

		center.add(left);
		center.add(right);

		add(center, BorderLayout.CENTER);

		JPanel messagePanel = new JPanel();
		message = new JLabel(" ");
		messagePanel.add(message);

		add(messagePanel, BorderLayout.PAGE_END);
	}

	private Object[][] createTableContent(String category) {
		try {
			Properties properties = server.getProducts(category);
			Set<Object> list = properties.keySet();
			Object[][] data = new Object[list.size()][4];

			int i = 0;
			for (Object key : list) {
				if (key instanceof ProductInterface) {
					ProductInterface pr = (ProductInterface) key;
					data[i][0] = pr.getCode();
					data[i][1] = pr.getName();
					data[i][2] = nf.format(pr.getPrice());
					data[i][3] = pr.getCategory();
					i++;
				}
			}
			return data;
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return null;
	}

	class dropdownHandler implements ActionListener {
		@SuppressWarnings("rawtypes")
		public void actionPerformed(ActionEvent e) {
			JComboBox cb = (JComboBox) e.getSource();
			String item = cb.getSelectedItem().toString();
			if (item.equals("")) {
				selected.setText("Alle producten");
			} else {
				selected.setText("Geselecteerde categorie: " + item);
			}
			Object[][] data = createTableContent(item);
			ProductTableModel model = (ProductTableModel) table.getModel();
			model.insertAndClear(data);
		}
	}

	class sessionHandler implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			try {
				int id = server.newSession(nameField.getText());
				if (id != 0) {
					setId(id);
					setName(nameField.getText());
					setMessage("Winkelmand " + id + " voor " + nameField.getText(),
							false);
					nameField.setEnabled(false);
					dropdown.setEnabled(true);
					newOrder.setEnabled(true);
					amountField.setEnabled(true);
					table.setEnabled(true);
					String res = manager.updateOverview(server, getName(),
							getId());
					overview.setText(res);
					editorScrollPane.getViewport().revalidate();
				} else {
					setMessage("Geen naam opgegeven!", true);
				}
			} catch (RemoteException e1) {
				e1.printStackTrace();
			}
		}
	}

	class orderHandler implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			try {
				int row = table.getSelectedRow();
				String amountText = amountField.getText();
				if (amountText.equalsIgnoreCase("")) {
					setMessage("Geen aantal ingevuld!", true);
				} else if (row < 0) {
					setMessage("Geen product geselecteerd!", true);
				} else {
					ProductTableModel model = (ProductTableModel) table
							.getModel();
					String code = (String) model.getValueAt(row, 0);
					int amount = 0;
					try {
						amount = Integer.parseInt(amountText);
						if (amount < 1) {
							setMessage("Aantal is kleiner dan 1", true);
						} else {
							boolean order = server.order(getName(), getId(),
									code, amount);
							if (order) {
								setMessage(code + " is " + amount
										+ " keer toegevoegd aan winkelmand!",
										false);
								String res = manager.updateOverview(server,
										getName(), getId());
								overview.setText(res);
								overview.invalidate();
								newConfirm.setEnabled(true);
							} else {
								setMessage("Toevoegen is mislukt!", true);
							}
						}
					} catch (NumberFormatException numberExcept) {
						setMessage("Aantal is geen getal!", true);
					}
				}
				editorScrollPane.revalidate();
			} catch (RemoteException e1) {
				e1.printStackTrace();
			}
		}
	}

	class confirmHandler implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			try {
				boolean success = server.confirmOrder(getName(), getId());
				if (success) {
					setMessage("Het plaatsen van een order was succesvol!",
							false);
					int id = server.newSession(getName());
					if (id != 0) {
						setId(id);
					}
					String res = manager.updateOverview(server, getName(),
							getId());
					overview.setText(res);
				} else {
					setMessage(
							"Bestelling is mislukt! Een product is niet voorradig.",
							true);
				}
			} catch (RemoteException e1) {
				e1.printStackTrace();
			}
		}
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	private void setMessage(String text, boolean error) {
		message.setText(text);
		Color c = (error) ? Color.red : Color.black;
		message.setForeground(c);
	}

}